package com.github.byakkili.bim.core;

import cn.hutool.core.util.StrUtil;
import com.github.byakkili.bim.core.cluster.ClusterManager;
import com.github.byakkili.bim.core.handler.command.CommandProcessor;
import com.github.byakkili.bim.core.interceptor.CommandInterceptor;
import com.github.byakkili.bim.core.listener.SessionListener;
import com.github.byakkili.bim.core.protocol.Protocol;
import com.github.byakkili.bim.core.threadpool.ThreadPool;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author Guannian Li
 */
@Setter
@Getter
@NoArgsConstructor
public class BimConfiguration {
    /**
     * 绑定IP
     */
    private String bindIp = Constants.LOCALHOST;
    /**
     * 绑定端口
     */
    private int bindPort = 9000;
    /**
     * 超时(秒)
     */
    private int idleTimeout = 30;
    /**
     * TCP Keep Alive
     */
    private boolean keepAlive = false;
    /**
     * IO线程数
     */
    private int ioThread = Constants.DEFAULT_IO_THREADS;
    /**
     * 业务线程池
     */
    private ThreadPool threadPool;
    /**
     * 集群
     */
    private ClusterManager clusterManager;
    /**
     * 协议
     */
    private final List<Protocol> protocols = new CopyOnWriteArrayList<>();
    /**
     * 命令处理器
     */
    private final Map<Integer, CommandProcessor> commandProcessors = new ConcurrentHashMap<>();
    /**
     * 会话监听器
     */
    private final List<SessionListener> sessionListeners = new CopyOnWriteArrayList<>();
    /**
     * 命令拦截器
     */
    private final List<CommandInterceptor> commandInterceptors = new CopyOnWriteArrayList<>();

    /**
     * 添加命令处理器
     *
     * @param commandProcessor 命令处理器
     */
    public void addCommandProcessor(CommandProcessor commandProcessor) {
        int command = commandProcessor.command();
        if (commandProcessors.containsKey(command)) {
            throw new IllegalArgumentException(StrUtil.format("Command '{}' repeat.", command));
        }
        commandProcessors.put(command, commandProcessor);
    }
}
